

import dayjs from "dayjs"

import store from "@/store";
import { useMainStore } from "@/store/modules/store";
import serviceTools from "@/common/service";
import Guid from "@/common/guid";
import useService from "@/hooks/useService";

import { LowcodeDefaultValueType } from "../interface";
import type { LowcodeCodeRule, LowcodePagePanelComponentItem } from "../interface";
import type { LowcodeDefHookProxy, GenerateLowcodeDefProxy } from "./interface";
import { lowcodeNumberToRuntimePrecision, lowcodeTenantField } from "../constant.js";
import { isLowcodeNumComponent } from "../utils.js";
import useDateTimeDefVal from "./useDateTimeDefVal.js";

const useLowcodeDef = (hookProxy?: LowcodeDefHookProxy) => {
  const mainService = useService({ prefix: "mainApi" });
  const mainStore = useMainStore();
  const { calculateDValue } = useDateTimeDefVal({ mdCode: hookProxy?.mdCode || "" });
  const loginInfo = store?.state?.value?.main?.loginInfo || {};
  const lowcodeDefBaseVar = ["#当前用户", "#当前用户名", "#默认人事部门", "#默认人事部门名称", "#当前机构", "#当前机构名", "#当前机构类型", "#36位全局唯一编码"]

  const convertBaseVarValue = (cFGValue: string)=> {
    let newValue = "";
    switch (cFGValue) {
      case "#当前用户":
        newValue = loginInfo?.sUser || "";
        break;
      case "#当前用户名":
        newValue = loginInfo?.sUserName || "";
        break;
      // case "#默认人事部门": // TODO 移动端暂时还取不到这些值
      //   newValue = loginInfo?.sUser || "";
      //   break;
      // case "#默认人事部门名称":
      //   newValue = loginInfo?.sUser || "";
      //   break;
      case "#当前机构":
        newValue = loginInfo?.sUserStore || "";
        break;
      case "#当前机构名":
        newValue = loginInfo?.sUserStoreName || "";
        break;
      case "#当前机构类型":
        newValue = loginInfo?.sUserStoreHier || "";
        break;
      case "#36位全局唯一编码":
        newValue = Guid.NewGuid().ToString();
        break;
    }

    return newValue;
  };

  const createLowcodeRuleCode = async (editTableName?: string, codeDBField?: string, codeRule?: LowcodeCodeRule) => {
    if(!editTableName || !codeDBField || !codeRule) {
      return "";
    }

    const variable = codeRule.variable ? (lowcodeDefBaseVar.includes(codeRule.variable) ?  convertBaseVarValue(codeRule.variable) : "") : "";
    const flowLen = (codeRule?.flowLen || 0) < 2 ? 6 : codeRule?.flowLen;
    const billCFG = {
      c_bill_header: codeRule?.prefix || "",
      c_collation: codeRule?.collation || "",
      c_date_format: codeRule?.dateFormat || "",
      c_variable: "变量",
      c_is_dash_connect: codeRule?.isDashConnect === "1"
    };

    const billInfo = {
      BillIdKeyValue: { key:codeDBField, value: "" },
      TableName: (editTableName || "").trim(),
      BillVariable:variable,
      FlowLen: flowLen,
      BillCFG: billCFG
    };
    const fetchReqProxy = { ModuleCode: hookProxy?.mdCode || "" };
    const fetchRes = await mainService.request<any, any>("单号生成服务", "EnjoyGetBillId", billInfo, "", "", fetchReqProxy);

    return (fetchRes || "").trim();
  };

  const asyncResolve = async (defData: { [key: string]: any }, fieldConf: LowcodePagePanelComponentItem, proxy?: GenerateLowcodeDefProxy) => {
    const { c_code, c_type, c_valuetype, c_defaultvalue, c_displayname_code, c_displayname_defaultvalue, c_format = "", bindFieldDBType } = fieldConf || {};
    const fCode = c_code || "", nameDValue = c_displayname_defaultvalue?.value || "";
    const isUploadComponent = c_type === "fileupload" || c_type === "imageupload";
    const isNumVal = isLowcodeNumComponent({ c_type, c_valuetype, bindFieldDBType });
    const { editTbName, panelType = "", panelData } = (proxy || {});
    const { codeRule, value = "", valueType, values } = c_defaultvalue || {};
    const rowIdx = panelData?.length || 0;

    if(fCode.trim() === lowcodeTenantField) {
      defData[fCode] = mainStore?.loginInfo?.sTenantId || ""; // TODO userData.TenantId || "";
      return;
    }

    let codeDVal: any = isUploadComponent ? Guid.NewGuid().ToString() : value || "";
    if (isNumVal) {
      const dotCount = (lowcodeNumberToRuntimePrecision as any)[c_format];
      codeDVal = (+codeDVal || 0).toFixed(dotCount);
    }

    if (c_defaultvalue) {
      switch (valueType) {
        case LowcodeDefaultValueType.单行默认值:
          codeDVal = (value || "")?.trim?.();
          break;
        case LowcodeDefaultValueType.多行默认值:
          codeDVal = (value || "")?.trim?.();
          Object.prototype.toString.call(values) === "[object Array]" && values?.[rowIdx] && (codeDVal = values[rowIdx]?.trim?.());
          break;
        case LowcodeDefaultValueType.系统变量:
          codeDVal = lowcodeDefBaseVar.includes(value) ? convertBaseVarValue(value) : await calculateDValue(value, c_format);
          break;
        // case LowcodeDefaultValueType.表单变量:
        //   codeDVal = (value || "")?.trim?.();
        //   break; // TODO 暂时还没有使用此项的
        case LowcodeDefaultValueType.按规则生成编码:
          codeDVal = await createLowcodeRuleCode(editTbName, fCode, codeRule);
          break;
      }

      if (codeDVal === "#行号" && isNumVal) {
        const codeSortValAry = panelData?.map(r => (+r?.[fCode] || 1));
	      const maxSortVal = (Array.isArray(codeSortValAry) && codeSortValAry?.length) ? Math.max(...codeSortValAry) : 0;
        codeDVal = ["1", "2"].includes(panelType) ? 1 : (maxSortVal + 1);
      }
    }

    if (!codeDVal && ["2", "3"].includes(bindFieldDBType || "")) {
      codeDVal = 0;
    }
    if (!codeDVal && ["4", "5"].includes(bindFieldDBType || "")) {
      codeDVal = null;
    }

    defData[fCode] = codeDVal;
    if (c_displayname_code) {
      defData[c_displayname_code] = nameDValue?.startsWith("#") ? await convertBaseVarValue(nameDValue) : nameDValue;
    }
  };

  const generateLowcodeDef = async (proxy?: GenerateLowcodeDefProxy) => {
    const { Components, ...restProxy } = proxy || {};
    const defData: { [key: string]: any } = {};
    if (!Array.isArray(Components) || !Components?.length) {
      return defData;
    }
    for (let i = 0; i < Components.length; i++) {
      const currFieldConf = Components[i] || {};
      const { c_code: fieldKey, c_defaultvalue } = currFieldConf;
      if (!fieldKey) {
        continue;
      }
      
      await asyncResolve(defData, currFieldConf, restProxy);
    }

    // console.log("generateLowcodeDef Components defData === ", Components, defData);
    return defData;
  };

  return { generateLowcodeDef };
};

export default useLowcodeDef;
